package com.njit;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;

/**
 * Swing 界面工具，用于将 BIN 文件转换为 OTA
 */
public class BinToOtaTool extends JFrame implements ActionListener {
    private JTextField binField;
    private JTextField otaField;
    //型号名称
    private JTextField  modelNameField;
    //固件版本
    private JTextField versionField;
    //固件最高版本
    private JTextField  maxVersionField;
    //固件最低版本
    private JTextField  minVersionField;

    private JButton chooseBinButton;
    private JButton chooseOtaButton;
    private JButton generateButton;

    public BinToOtaTool() {
        super("嵌入式文件转OTA");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(500, 400);
        setLocationRelativeTo(null);

        binField = new JTextField(25);
        otaField = new JTextField(25);
        versionField = new JTextField(10);

        chooseBinButton = new JButton("选择 BIN|ELF|HEX文件");
        chooseOtaButton = new JButton("选择存储目录");
        generateButton = new JButton("生成 OTA文件");

        //添加事件监听机制
        chooseBinButton.addActionListener(this);
        chooseOtaButton.addActionListener(this);
        generateButton.addActionListener(this);

        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(5, 5, 5, 5);
        c.fill = GridBagConstraints.HORIZONTAL;

        c.gridx = 0; c.gridy = 0;
        panel.add(new JLabel("原始 BIN|ELF|HEX 文件："), c);
        c.gridx = 1;
        panel.add(binField, c);
        c.gridx = 2;
        panel.add(chooseBinButton, c);

        c.gridx = 0; c.gridy = 1;
        panel.add(new JLabel("输出 OTA文件的目录："), c);
        c.gridx = 1;
        panel.add(otaField, c);
        c.gridx = 2;
        panel.add(chooseOtaButton, c);

        modelNameField = new JTextField(10);
        maxVersionField = new JTextField(10);
        minVersionField = new JTextField(10);

        c.gridx = 0; c.gridy = 2;
        panel.add(new JLabel("型号名称："), c);
        c.gridx = 1;
        panel.add(modelNameField, c);

        c.gridx = 0; c.gridy = 3;
        panel.add(new JLabel("固件版本号："), c);
        c.gridx = 1;
        panel.add(versionField, c);

        c.gridx = 0; c.gridy = 4;
        panel.add(new JLabel("最低支持版本："), c);
        c.gridx = 1;
        panel.add(minVersionField, c);

        c.gridx = 0; c.gridy = 5;
        panel.add(new JLabel("最高支持版本："), c);
        c.gridx = 1;
        panel.add(maxVersionField, c);

        c.gridx = 1; c.gridy = 6;
        panel.add(generateButton, c);

        add(panel);
        loadLastImportData();  // ← 读取上次保存的 importdata.txt
    }
    public void  loadLastImportData(){
        try {
            Path tmpDir  = Paths.get("tmp");
            Path dataFile = tmpDir.resolve("importdata.txt");
            if (!Files.exists(dataFile)) {
                return;  // 文件不存在就跳过
            }
            Properties p = new Properties();
            try (InputStream in = Files.newInputStream(dataFile)) {
                p.load(in);
            }
            versionField.setText(   p.getProperty("version",    "") );
            modelNameField.setText( p.getProperty("modelName",  "") );
            minVersionField.setText(p.getProperty("minVersion",""));
            maxVersionField.setText(p.getProperty("maxVersion",""));
        } catch (IOException ex) {
            ex.printStackTrace();  // 读取失败，打印日志
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == chooseBinButton) {
            JFileChooser chooser = new JFileChooser();
            chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
            if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                binField.setText(chooser.getSelectedFile().getAbsolutePath());
            }
        } else if (e.getSource() == chooseOtaButton) {
            JFileChooser chooser = new JFileChooser();
            chooser.setDialogTitle("请选择输出目录");
            // 只让选择目录
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            // 不显示“所有文件”那一行
            chooser.setAcceptAllFileFilterUsed(false);
            if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                // 只取目录路径
                String dir = chooser.getSelectedFile().getAbsolutePath();
                otaField.setText(dir);
            }
        } else if (e.getSource() == generateButton) {
            //获取文本
            String binPathStr = binField.getText().trim();
            String fileName=binPathStr.substring(binPathStr.lastIndexOf(File.separator),binPathStr.lastIndexOf("."));

            String otaPathStr = otaField.getText().trim()+fileName+".ota";

            String versionStr = versionField.getText().trim();
            String modelName=modelNameField.getText().trim();

            Integer minVersion=Integer.parseInt(minVersionField.getText().trim());
            Integer maxVersion=Integer.parseInt(maxVersionField.getText().trim());

            int version = Integer.parseInt(versionStr);
            if (binPathStr.isEmpty() || otaPathStr.isEmpty() || versionStr.isEmpty()|| modelName.isEmpty()|| minVersion==null||maxVersion==null) {
                JOptionPane.showMessageDialog(this, "请填写所有字段。", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            try {
                Path binPath = Paths.get(binPathStr);
                Path newBinPath = null;
                if (binPath.toString().endsWith("hex")){
                    String suffixElf = binPath.toString().substring(0, binPath.toString().lastIndexOf("hex"));
                    newBinPath = binPath.resolve(suffixElf+"bin");
                    System.out.println("新的bin地址"+newBinPath.toString());
                    BinToOtaUtil.convertHexToBin(binPath,newBinPath);
                }else if (binPath.toString().endsWith("elf")){
                    try {
                        String suffixHex = binPath.toString().substring(0, binPath.toString().lastIndexOf("elf"));
                        newBinPath = binPath.resolve(suffixHex+"bin");
                        System.out.println("新的bin地址"+newBinPath.toString());
                        BinToOtaUtil.convertElfToBin(binPath,newBinPath);
                    } catch (InterruptedException ex) {
                        throw new RuntimeException(ex);
                    }
                }else{
                    newBinPath=binPath;
                }
                Path otaPath = Paths.get(otaPathStr);

                BinToOtaUtil.convertBinToOta(newBinPath, otaPath, version,modelName,minVersion,maxVersion);

                JOptionPane.showMessageDialog(this, "已生成 OTA 文件：" + otaPath, "成功", JOptionPane.INFORMATION_MESSAGE);
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "版本号必须是整数。", "错误", JOptionPane.ERROR_MESSAGE);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "生成过程中发生错误：" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                ex.printStackTrace();
            }
            try {
                Path tmpDir   = Paths.get("tmp");
                if (!Files.exists(tmpDir)) {
                    Files.createDirectories(tmpDir);
                }
                Path dataFile = tmpDir.resolve("importdata.txt");

                Properties p = new Properties();
                p.setProperty("version",    versionStr);
                p.setProperty("modelName",  modelName);
                p.setProperty("minVersion", minVersion.toString());
                p.setProperty("maxVersion", maxVersion.toString());

                try (OutputStream out = Files.newOutputStream(dataFile)) {
                    p.store(out, "Last import data");
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();  // 写入失败打印日志
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new BinToOtaTool().setVisible(true);
        });
    }
}

